//package com.rxyb.ops.filter;
//
//import io.github.bucket4j.Bandwidth;
//import io.github.bucket4j.Bucket;
//import io.github.bucket4j.Bucket4j;
//import io.github.bucket4j.Refill;
//import lombok.extern.slf4j.Slf4j;
//import org.springframework.boot.autoconfigure.couchbase.CouchbaseProperties;
//import org.springframework.cloud.gateway.filter.GatewayFilter;
//import org.springframework.cloud.gateway.filter.GatewayFilterChain;
//import org.springframework.context.annotation.Configuration;
//import org.springframework.core.Ordered;
//import org.springframework.http.HttpStatus;
//import org.springframework.stereotype.Component;
//import org.springframework.web.server.ServerWebExchange;
//import reactor.core.publisher.Mono;
//
//import java.time.Duration;
//import java.util.Map;
//import java.util.concurrent.ConcurrentHashMap;
//
///**
// * @author YJH
// * @version 1.0
// * @description 统计某个或者某种路由的处理时间长度
// * @date 2020/5/13  16:19
// */
//@Slf4j
////@Configuration
//public class CustomGatewayFilter implements GatewayFilter, Ordered {
//
//    private static final String COUNT_START_TIME = "count_start_time";
//
//    /**
//     * 单机版网关限流使用 ConcurrentHashMap 存储
//     * 如果是分布式集群 使用redis
//     */
//    private static final Map<String, Bucket> LOCAL_CACHE = new ConcurrentHashMap<>();
//
//    /*桶的最大容量 既能装载token 的最大数量*/
//    int copacity;
//
//    /*每次token 补充量*/
//    int refillTokens;
//
//    /*补充Token 的时间隔离*/
//    Duration refillDuration;
//
//    public CustomGatewayFilter(int copacity, int refillTokens, Duration refillDuration) {
//        this.copacity = copacity;
//        this.refillTokens = refillTokens;
//        this.refillDuration = refillDuration;
//    }
//
//    public CustomGatewayFilter() {
//    }
//
//    private Bucket createNewBucket() {
//        Refill refill = Refill.of(refillTokens, refillDuration);
//        Bandwidth classic = Bandwidth.classic(copacity, refill);
//        return Bucket4j.builder().addLimit(classic).build();
//    }
//
//
//    @Override
//    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//        exchange.getAttributes().put(COUNT_START_TIME, System.currentTimeMillis());
//        // token 拦截
//        String token = exchange.getRequest().getQueryParams().getFirst("authToken");
//        if (null == token || token.isEmpty()) {
//            exchange.getResponse().setStatusCode(HttpStatus.MULTI_STATUS);
//            return exchange.getResponse().setComplete();
//        }
//        // 限流
//        String ip = exchange.getRequest().getRemoteAddress().getAddress().getHostAddress();
//        Bucket bucket = LOCAL_CACHE.computeIfAbsent(ip, k -> createNewBucket());
//        log.info("IP: {} , 令牌桶可用的token数量:{} ", ip, bucket.getAvailableTokens());
//        if (!bucket.tryConsume(1)) {
//            exchange.getResponse().setStatusCode(HttpStatus.TOO_MANY_REQUESTS);
//            return exchange.getResponse().setComplete();
//        }
//        return chain.filter(exchange).then(
//                Mono.fromRunnable(() -> {
//                    // 开始时间
//                    Long startTime = exchange.getAttribute(COUNT_START_TIME);
//                    // 结束时间
//                    Long endTime = (System.currentTimeMillis() - startTime);
//                    if (null != startTime) {
//                        log.info(exchange.getRequest().getURI().getRawPath() + ":" + endTime + "s");
//                    }
//                })
//        );
//    }
//
//    @Override
//    public int getOrder() {
//        return Ordered.HIGHEST_PRECEDENCE;
//    }
//}
